<?php


namespace BoojasrFramework\ServicesContainer;


class Container implements ContainerInterface
{

    protected $services = [];

    protected $classIdService = [];

    protected $removeIds = [];

    protected $privates = [];

    protected $compiler;

    /**
     * @return Compiler
     */
    public function getCompiler(){
        if (!isset($this->compiler)){
            $this->compiler = new Compiler();
        }
        return $this->compiler;
    }

    /**
     * @param $id
     * @param $service
     * @return Container
     */
    public function set($id, $service)
    {
        $this->services[$id] = $service;
        $this->classIdService[get_class($service)] = $service;
        return $this;
    }

    public function get($id,$hasCompile=true)
    {
        if ($id == "service_container"){
            return $this;
        }

        if(in_array($id,$this->getRemoveIds())||in_array($id,$this->getPrivates())){
            return null;
        }

        if (!$hasCompile){
            return null;
        }

        if($this->has($id)){
            return $this->services[$id];
        }

        if (isset($this->classIdService[$id])){
            return $this->classIdService[$id];
        }

        return $this->load($id);
    }

    public function load($id){
        return $this->getCompiler()->compileService($this,$id);
    }

    /**
     * @param $id
     * @return bool
     */
    public function has($id)
    {
        return isset($this->services[$id]);
    }

    /**
     * @return array
     */
    public function getRemoveIds()
    {
        return $this->removeIds;
    }

    /**
     * @param array $removeIds
     */
    public function setRemoveIds($removeIds)
    {
        $this->removeIds = $removeIds;
    }

    /**
     * @param $id
     * @return $this
     */
    public function addRemoveIds($id){
        $this->removeIds[] = $id;

        return $this;
    }

    /**
     * @param $id
     * @return bool
     */
    public function hasRemoveId($id){
        return isset($this->removeIds[$id]);
    }

    /**
     * @return array
     */
    public function getPrivates()
    {
        return $this->privates;
    }

    /**
     * @param array $privates
     */
    public function setPrivates($privates)
    {
        $this->privates = $privates;
    }

    /**
     * @param $id
     * @return $this
     */
    public function addPrivates($id){
        $this->privates[] = $id;

        return $this;
    }


}
